/*
 *   Licensed to the Apache Software Foundation (ASF) under one
 *   or more contributor license agreements.  See the NOTICE file
 *   distributed with this work for additional information
 *   regarding copyright ownership.  The ASF licenses this file
 *   to you under the Apache License, Version 2.0 (the
 *   "License"); you may not use this file except in compliance
 *   with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing,
 *   software distributed under the License is distributed on an
 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *   KIND, either express or implied.  See the License for the
 *   specific language governing permissions and limitations
 *   under the License.
 *
 */

package org.apache.directory.server.codec.json;

import java.lang.reflect.Type;

import org.apache.directory.server.http.AppConstants;
import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
import org.apache.directory.shared.ldap.message.AbstractResultResponse;
import org.apache.directory.shared.ldap.message.AddResponseImpl;
import org.apache.directory.shared.ldap.message.BindResponseImpl;
import org.apache.directory.shared.ldap.message.CompareResponseImpl;
import org.apache.directory.shared.ldap.message.DeleteResponseImpl;
import org.apache.directory.shared.ldap.message.LdapResult;
import org.apache.directory.shared.ldap.message.LdapResultImpl;
import org.apache.directory.shared.ldap.message.ModifyDnResponseImpl;
import org.apache.directory.shared.ldap.message.ModifyResponseImpl;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * TODO AbstractResultResponseCodec.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class AbstractResultResponseCodec implements JsonSerializer<AbstractResultResponse>, JsonDeserializer<AbstractResultResponse>
{

    public AbstractResultResponse deserialize( JsonElement element, Type typeOfT, JsonDeserializationContext context )
        throws JsonParseException
    {
        JsonObject json = element.getAsJsonObject();
        
        AbstractResultResponse response = null;
        MessageTypeEnum type = MessageTypeEnum.valueOf( json.get( "type" ).getAsString() );
        
        switch( type )
        {
            case BIND_RESPONSE: response = new BindResponseImpl();
                                break;
                                
            case ADD_RESPONSE: response = new AddResponseImpl();
                               break;
                               
            case COMPARE_RESPONSE: response = new CompareResponseImpl();
                                   break;
                                   
            case DEL_RESPONSE: response = new DeleteResponseImpl();
                               break;
                               
            case MODIFY_RESPONSE: response = new ModifyResponseImpl();
                                  break;
                                  
            case MODIFYDN_RESPONSE: response = new ModifyDnResponseImpl();
                                    break;
                                    
            default: new IllegalArgumentException( "message response type " + type + " is not yet supported" );
        }
        
        JsonElement messageId = json.get( "messageId" );
        if( messageId != null )
        {
            response.setMessageId( messageId.getAsInt() );
        }
        
        LdapResult parsedResult = JsonBuilder.fromJson( json.get( AppConstants.LDAP_RESULT_KEY ), LdapResultImpl.class );
        
        LdapResult respResult = response.getLdapResult();
        respResult.setErrorMessage( parsedResult.getErrorMessage() );
        respResult.setMatchedDn( parsedResult.getMatchedDn() );
        respResult.setReferral( parsedResult.getReferral() );
        respResult.setResultCode( parsedResult.getResultCode() );
        
        return response;
    }

    public JsonElement serialize( AbstractResultResponse src, Type typeOfSrc, JsonSerializationContext context )
    {
        JsonObject json = new JsonObject();
        
        json.addProperty( "messageId", src.getMessageId() );
        json.addProperty( "type", src.getType().name() );
        json.add( AppConstants.LDAP_RESULT_KEY, JsonBuilder.toJsonTree( src.getLdapResult() ) );
        
        return json;
    }

}
